/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package compumundohipermegared;

import ConstantesProcotolo.Protocolo;
import java.io.IOException;
import java.io.Serializable;
import java.net.DatagramPacket;
import java.util.ArrayList;
import net.jxta.socket.JxtaMulticastSocket;

/**
 *
 * @author Arkan
 */
public class EnviadorFotoMasParecida extends Thread implements Serializable{
     /**
     * Indicador de versión para la serialización
     */
    private static final long serialVersionUID = 400L;
    
    private JxtaMulticastSocket jxtaMulticastSocket;
    private ArrayList<Foto> fotosEnMiEquipo;
    private Compartidor compartidor;
    private boolean estamosBloqueados;
    /**
     * indica si acabo de preguntar si estamos bloqueados
     */
    private boolean acaboDePreguntarSiEstamosBloqueados;
    
    EnviadorFotoMasParecida(JxtaMulticastSocket jxtaMulticastSocket, ArrayList<Foto> fotosEnMiEquipo, Compartidor padre) {
        this.jxtaMulticastSocket = jxtaMulticastSocket;
        this.fotosEnMiEquipo = fotosEnMiEquipo;
        compartidor=padre;
        estamosBloqueados=false;
        acaboDePreguntarSiEstamosBloqueados= false;
    }

    public void run()
    {
        try 
        {
            while (true) 
            {
                System.out.println(jxtaMulticastSocket);
                System.out.println("Esperando Conexiones multcast:");
                //System.out.println("intet address del socket: "+jxtaMulticastSocket.getInetAddress().toString());
                //System.out.println("local socket address del socket: " + jxtaMulticastSocket.getLocalSocketAddress());
//                System.out.println("esta conectado: " + jxtaMulticastSocket.isConnected());
//                System.out.println("is bound: " + jxtaMulticastSocket.isBound());
//               
//                System.out.println("Paso 5");
                byte[] buf = new byte[1000];
                DatagramPacket recv = new DatagramPacket(buf, buf.length);
                jxtaMulticastSocket.receive(recv);
               // System.out.println("Paso 6");
                String mensaje = new String(recv.getData(), 0);

                System.out.println("llego el mensaje: " + mensaje);

                if (mensaje.startsWith(Protocolo.ENVIEME_FOTO_MAS_PARECIDA.toString()))
                {  
                    String[] partesMensaje = mensaje.split(":");
                    String anchoStr = partesMensaje[1];
                    String altoStr = partesMensaje[2];
                    String idfoto = partesMensaje[3];
                    
                    int anchoImagen = Integer.valueOf(anchoStr);
                    int altoImagen = Integer.valueOf(altoStr);
                    
                    compartidor.asignarDatosBuscarFotoMasParecida(anchoImagen, altoImagen, idfoto);
                    
                    Foto fotoMasParecida = buscarFotoMasParecida(anchoImagen, altoImagen, idfoto);
                    
                    if (fotoMasParecida!=null){
                        // respondo con el id de la foto, seguido del puntaje
                        String respuesta=fotoMasParecida.getId()+":"+calcularPuntajeFoto(fotoMasParecida, anchoImagen, altoImagen);
                        DatagramPacket dp = new DatagramPacket( respuesta.getBytes( ), respuesta.length( ) );
                        jxtaMulticastSocket.send( dp );
                        
                        compartidor.envioFotoMasParecida( );
                    }      
                }
                else if( mensaje.equals( Protocolo.BLOQUEENSE.toString( ) ) )
                {
                    compartidor.bloquearSistema( );
                    estamosBloqueados=true;
                }
                else if( mensaje.equals( Protocolo.TERMINE_RECIBIR_FOTOS.toString( ) ) )
                {
                    compartidor.desbloquear( );
                    estamosBloqueados=false;
                }
                else if(mensaje.startsWith(Protocolo.PREGUNTO_SI_ESTAN_BLOQUEADOS.toString()) )
                {
                   
                    String nombreUsuarioQuePide = mensaje.split(":")[1];
                            
                    String miNombre = compartidor.darNombreUsuario();
                    if(!nombreUsuarioQuePide.equals(miNombre)){
                        if(estamosBloqueados ){
                        
                        mensaje = Protocolo.SI_ESTAMOS_BLOQUEADOS.toString()+":"+nombreUsuarioQuePide;
                        DatagramPacket dp = new DatagramPacket(mensaje.getBytes(), mensaje.length());
                        
                            jxtaMulticastSocket.send(dp);
                        
                        
                        }else{

                            mensaje = Protocolo.NO_ESTAMOS_BLOQUEADOS.toString();
                            DatagramPacket dp = new DatagramPacket(mensaje.getBytes(), mensaje.length());

                                jxtaMulticastSocket.send(dp);

                        }
                    }
                    else
                    {
                        System.out.println("no voy a responder eso!!! porque yo soy el que pregunto");
                        acaboDePreguntarSiEstamosBloqueados=true;
                    }
                    
                }
                else if( mensaje.startsWith(Protocolo.SI_ESTAMOS_BLOQUEADOS.toString()))
                {
                    String nombreDeAQuienLeResponden= mensaje.split(":")[1];
                    String miNombre= compartidor.darNombreUsuario();
                    if(nombreDeAQuienLeResponden.equals(miNombre)&& acaboDePreguntarSiEstamosBloqueados)
                    {
                        compartidor.bloquearSistema();
                        acaboDePreguntarSiEstamosBloqueados=false;
                    }
                    else
                    {
                        System.out.println("esto no va para mi, entonces no me bloqueo");
                    }
                    
                } 
                else if( mensaje.startsWith( Protocolo.CONTINUAR_MANDANDO_FOTO_MAS_PARECIDA.toString( ) ) )
                {
                    if( compartidor.estaBuscandoFotoMasParecida( ) )
                    {
                        String idfoto = compartidor.darIdFoto( );       
                        int anchoImagen = compartidor.darAncho( );
                        int altoImagen = compartidor.darAlto( );

                        compartidor.asignarDatosBuscarFotoMasParecida(anchoImagen, altoImagen, idfoto);

                        Foto fotoMasParecida = buscarFotoMasParecida(anchoImagen, altoImagen, idfoto);

                        if (fotoMasParecida!=null){
                            // respondo con el id de la foto, seguido del puntaje
                            String respuesta=fotoMasParecida.getId()+":"+calcularPuntajeFoto(fotoMasParecida, anchoImagen, altoImagen);
                            DatagramPacket dp = new DatagramPacket( respuesta.getBytes( ), respuesta.length( ) );
                            jxtaMulticastSocket.send( dp );

                            compartidor.envioFotoMasParecida( );
                        } 
                    }
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * retorna la foto mas parecida a los datos que llegan por parametro
     * si el id es el mismo, no la incluye en la cuenta
     * @param anchoImagen
     * @param altoImagen
     * @param idfoto
     * @return null si no tiene fotos, de lo contrario retorna la foto mas parecida
     */
    private Foto buscarFotoMasParecida(int anchoImagen, int altoImagen, String idfoto) {
        
        int puntajeMaximo=Integer.MAX_VALUE;
        Foto fotoMasParecida=null;
        for (int i = 0; i < fotosEnMiEquipo.size(); i++) {
            Foto foto = fotosEnMiEquipo.get(i);
            if(!idfoto.equals(foto.getId())){
                
                int puntajeActual = calcularPuntajeFoto(foto, anchoImagen,altoImagen);
                if(puntajeActual< puntajeMaximo){
                    puntajeMaximo=puntajeActual;
                    fotoMasParecida = foto;
                }
                
            }
            
        }
        return fotoMasParecida;
    }
    /**
     * calcula el puntaje de la foto respecto a unos datos dados por parametro
     * el puntaje compara el area y la proporción entre el ancho y el alto
     * entre mas cercano sera el puntaje a cero, mas parecida es la foto
     * @param foto
     * @param anchoImagen
     * @param altoImagen
     * @return 
     */
    private int calcularPuntajeFoto(Foto foto, int anchoImagen, int altoImagen) {
        int altoFotoMia = foto.getAltoImagen();
        int anchoFotoMia = foto.getAnchoImagen();
        
        double proporcionFotoMia = altoFotoMia / anchoFotoMia;
        double areaFotoMia = altoFotoMia*anchoFotoMia;
        
        double proporcionFotoExterna = altoImagen / anchoImagen;
        double areaFotoExterna = altoImagen * anchoImagen;
        
        int puntajeProporcion = Math.abs( (int) ((proporcionFotoExterna-proporcionFotoMia)*1000) );
        int puntajeArea = Math.abs( (int) ((areaFotoExterna-areaFotoMia)*1000) );
        
        return puntajeArea+puntajeProporcion;
        
    }

  
}
